﻿using System;
using RayD.Repository.Entites.SystemModule;
using System.Collections.Generic;
using System.Text;
using RayD.Repository;
using RayD.Repository.Core;
using RayD.Core;
using Dapper;
using System.Data;

namespace RayD.App.SystemModule
{
    public class LogApp
    {
        #region 构造函数注入
        private IRepository BaseRepository;
        public LogApp(IRepository repository)
        {
            this.BaseRepository = repository;
        }
        #endregion

        #region 获取数据
        /// <summary>
        /// 获取分页列表数据
        /// </summary>
        /// <param name="queryJson">查询条件</param>
        /// <returns></returns>
        public IEnumerable<LogEntity> GetList(string queryJson)
        {
            var expression = LinqExtensions.True<LogEntity>();

            var queryParam = queryJson.ToJObject();
            if (!queryParam["B_CategoryId"].IsEmpty())
            {
                expression = expression.And(c => c.B_CategoryId == queryParam["B_CategoryId"].ToInt());
            }
            if (!queryParam["B_HttpMethod"].IsEmpty())
            {
                expression = expression.And(c => c.B_HttpMethod == queryParam["B_HttpMethod"].ToString());
            }
            if (!queryParam["B_ExecuteAddress"].IsEmpty())
            {
                expression = expression.And(c => c.B_ExecuteAddress.Contains(queryParam["B_ExecuteAddress"].ToString()));
            }
            if (!queryParam["B_OperateModule"].IsEmpty())
            {
                expression = expression.And(c => c.B_OperateModule.Contains(queryParam["B_OperateModule"].ToString()));
            }
            if (!queryParam["B_OperateTime"].IsEmpty())
            {
                expression = expression.And(c => c.B_OperateTime >= queryParam["B_OperateTime"][0].ToDate() && c.B_OperateTime <= queryParam["B_OperateTime"][1].ToDate());
            }
            return BaseRepository.IQueryable(expression);
        }
        /// <summary>
        /// 获取分页列表数据
        /// </summary>
        /// <param name="queryJson">查询条件</param>
        /// <param name="pagination">分页参数</param>
        /// <returns></returns>
        public IEnumerable<LogEntity> GetPageList(string queryJson, Pagination pagination)
        {
            var expression = LinqExtensions.True<LogEntity>();

            var queryParam = queryJson.ToJObject();
            if (!queryParam["B_CategoryId"].IsEmpty())
            {
                expression = expression.And(c => c.B_CategoryId == queryParam["B_CategoryId"].ToInt());
            }
            if (!queryParam["B_HttpMethod"].IsEmpty())
            {
                expression = expression.And(c => c.B_HttpMethod == queryParam["B_HttpMethod"].ToString());
            }
            if (!queryParam["B_ExecuteAddress"].IsEmpty())
            {
                expression = expression.And(c => c.B_ExecuteAddress.Contains(queryParam["B_ExecuteAddress"].ToString()));
            }
            if (!queryParam["B_OperateModule"].IsEmpty())
            {
                expression = expression.And(c => c.B_OperateModule.Contains(queryParam["B_OperateModule"].ToString()));
            }
            if (!queryParam["B_OperateTime"].IsEmpty())
            {
                expression = expression.And(c => c.B_OperateTime >= queryParam["B_OperateTime"][0].ToDate() && c.B_OperateTime <= queryParam["B_OperateTime"][1].ToDate());
            }
            return BaseRepository.FindList(expression, pagination);
        }
        #endregion

        #region 提交数据
        /// <summary>
        /// 写入日志（已登录）
        /// </summary>
        /// <param name="logCategory">日志类别</param>
        /// <param name="logExecuteResult">日志操作结果</param>
        /// <param name="executeResultJson">日志内容</param>
        /// <param name="httpMethod">请求方式</param>
        /// <param name="executeAddress">执行地址</param>
        /// <param name="executeArguments">执行参数</param>
        /// <param name="sourceObjectId">备份主键</param>
        /// <param name="sourceContentJson">备份Json</param>
        public void WriteLog(LogCategory logCategory
            , LogExecuteResult logExecuteResult
            , string executeResultJson
            , string httpMethod
            , string executeAddress
            , string executeArguments
            , string sourceObjectId
            , string sourceContentJson)
        {
            var userInfo = AuthenticationHelper.LoginUserInfo;
            LogEntity logEntity = new LogEntity()
            {
                B_LogId = Guid.NewGuid().ToString(),
                B_OperateTime = DateTime.Now.ToCstTime(),

                B_CategoryId = (int)logCategory,
                B_HttpMethod = httpMethod,
                B_ExecuteResultJson = executeResultJson,
                B_ExecuteResult = (int)logExecuteResult,
                B_SourceObjectId = sourceObjectId,
                B_SourceContentJson = sourceContentJson,
                B_OperateAccount = userInfo.account + $"({userInfo.realName})",
                B_OperateUserId = userInfo.userId,
                B_ExecuteAddress = executeAddress,
                B_ExecuteArguments = executeArguments,
                B_Browser = Net.Browser,
                B_Host = Net.Host,
                B_IPAddress = Net.Ip
            };

            BaseRepository.Insert(logEntity);
        }

        /// <summary>
        /// 写入日志（已登录）
        /// </summary>
        /// <param name="logCategory">日志类别</param>
        /// <param name="logExecuteResult">日志操作结果</param>
        /// <param name="executeResultJson">日志内容</param>
        /// <param name="httpMethod">请求方式</param>
        /// <param name="executeAddress">执行地址</param>
        /// <param name="executeArguments">执行参数</param>
        public void WriteLog(LogCategory logCategory
            , LogExecuteResult logExecuteResult
            , string executeResultJson
            , string httpMethod
            , string executeAddress
            , string executeArguments)
        {
            this.WriteLog(logCategory, logExecuteResult, executeResultJson, httpMethod, executeAddress, executeArguments, string.Empty, string.Empty);
        }

        /// <summary>
        /// 写入日志（已登录）
        /// </summary>
        /// <param name="logCategory">日志类别</param>
        /// <param name="logExecuteResult">日志操作结果</param>
        /// <param name="executeResultJson">日志内容</param>
        /// <param name="executeAddress">执行地址</param>
        /// <param name="executeArguments">执行参数</param>
        public void WriteLog(LogCategory logCategory
            , LogExecuteResult logExecuteResult
            , string executeResultJson
            , string executeAddress
            , string executeArguments)
        {
            this.WriteLog(logCategory, logExecuteResult, executeResultJson, string.Empty, executeAddress, executeArguments, string.Empty, string.Empty);
        }

        /// <summary>
        /// 写入成功日志（已登录）
        /// </summary>
        /// <param name="logCategory">日志类别</param>
        /// <param name="executeResultJson">日志内容</param>
        /// <param name="httpMethod">请求方式</param>
        /// <param name="executeAddress">执行地址</param>
        /// <param name="executeArguments">执行参数</param>
        public void WriteLog(LogCategory logCategory
            , string executeResultJson
            , string httpMethod
            , string executeAddress
            , string executeArguments)
        {
            this.WriteLog(logCategory, LogExecuteResult.Success, executeResultJson, httpMethod, executeAddress, executeArguments, string.Empty, string.Empty);
        }

        /// <summary>
        /// 写入成功日志（已登录）
        /// </summary>
        /// <param name="logCategory">日志类别</param>
        /// <param name="executeResultJson">日志内容</param>
        /// <param name="executeAddress">执行地址</param>
        /// <param name="executeArguments">执行参数</param>
        public void WriteLog(LogCategory logCategory
            , string executeResultJson
            , string executeAddress
            , string executeArguments)
        {
            this.WriteLog(logCategory, LogExecuteResult.Success, executeResultJson, string.Empty, executeAddress, executeArguments, string.Empty, string.Empty);
        }


        /// <summary>
        /// 写入日志（未登录）
        /// </summary>
        /// <param name="logCategory">日志类别</param>
        /// <param name="logExecuteResult">日志操作结果</param>
        /// <param name="executeResultJson">日志内容</param>
        /// <param name="httpMethod">请求方式</param>
        /// <param name="executeAddress">执行地址</param>
        /// <param name="executeArguments">执行参数</param>
        /// <param name="sourceObjectId">备份主键</param>
        /// <param name="sourceContentJson">备份Json</param>
        /// <param name="operateAccount">操作用户</param>
        /// <param name="operateUserId">操作用户Id</param>
        /// <param name="operateModule">操作模块</param>
        public void WriteLog(LogCategory logCategory
            , LogExecuteResult logExecuteResult
            , string executeResultJson
            , string httpMethod
            , string executeAddress
            , string executeArguments
            , string sourceObjectId
            , string sourceContentJson
            , string operateAccount
            , string operateUserId
            , string operateModule)
        {
            LogEntity logEntity = new LogEntity()
            {
                B_LogId = Guid.NewGuid().ToString(),
                B_OperateTime = DateTime.Now.ToCstTime(),

                B_CategoryId = (int)logCategory,
                B_HttpMethod = httpMethod,
                B_ExecuteResultJson = executeResultJson,
                B_ExecuteResult = (int)logExecuteResult,
                B_SourceObjectId = sourceObjectId,
                B_SourceContentJson = sourceContentJson,
                B_OperateAccount = operateAccount,
                B_OperateUserId = operateUserId,
                B_OperateModule = operateModule,
                B_ExecuteAddress = executeAddress,
                B_ExecuteArguments = executeArguments,
                B_Browser = Net.Browser,
                B_Host = Net.Host,
                B_IPAddress = Net.Ip
            };

            BaseRepository.Insert(logEntity);
        }

        /// <summary>
        /// 清空日志
        /// </summary>
        /// <param name="logCategory">日志类别</param>
        /// <param name="logKeepTime">日志保留日期</param>
        /// <returns></returns>
        public (bool, string) ClearLog(LogCategory logCategory, LogKeepTime logKeepTime)
        {
            DateTime operateTime = DateTime.Now.ToCstTime();
            switch (logKeepTime)
            {
                case LogKeepTime.ThreeMonth:
                    operateTime = DateTime.Now.ToCstTime().AddMonths(-3);
                    break;
                case LogKeepTime.OneMonth:
                    operateTime = DateTime.Now.ToCstTime().AddMonths(-1);
                    break;
                case LogKeepTime.OneWeek:
                    operateTime = DateTime.Now.ToCstTime().AddDays(-7);
                    break;
                case LogKeepTime.ClearAll:
                    break;
                default:
                    throw new Exception($"未知的枚举类型{typeof(LogKeepTime)}");
            }

            BaseRepository.Delete<LogEntity>(c => c.B_OperateTime <= operateTime && c.B_CategoryId == (int)logCategory);
            return (true, "清除成功！");
        }
        #endregion
    }
}
